﻿#include<iostream>
#include <assert.h>
using namespace std;

template<typename T>
class Varray
{
private:

    #define WALK_LENGTH 64;

public:
    
    Varray() :array(0), theSize(0), theCapacity(0) {    }
    Varray(const T& t, unsigned int n) :array(0), theSize(0), theCapacity(0) {
        while (n--) {
            push_back(t);
        }
    }

   
    Varray(const Varray<T>& other) :array(0), theSize(0), theCapacity(0) {
        *this = other;
    }


    Varray<T>& operator =(Varray<T>& other) {
        if (this == &other)
            return *this;
        clear();
        theSize = other.size();
        theCapacity = other.capacity();
        array = new T[theCapacity];
        for (unsigned int i = 0; i < theSize; ++i)
        {
            array[i] = other[i];
        }
        return *this;
    }


    ~Varray() {
        clear();
    }


    T& operator[](unsigned int pos) {
        assert(pos < theSize);
        return array[pos];
    }


    unsigned int size() {
        return theSize;
    }

  
    unsigned int capacity() {
        return theCapacity;
    }


    bool empty() {
        return theSize == 0;
    }


    void clear() {
        deallocator(array);
        array = 0;
        theSize = 0;
        theCapacity = 0;
    }


    void push_back(const T& t) {
        insert_after(theSize - 1, t);
    }


    void push_front(const T& t) {
        insert_before(0, t);
    }


    void insert_after(int pos, const T& t) {
        insert_before(pos + 1, t);
    }


    void insert_before(int pos, const T& t) {
        if (theSize == theCapacity) {
            T* oldArray = array;
            theCapacity += WALK_LENGTH;
            array = allocator(theCapacity);
            for (unsigned int i = 0; i < theSize; ++i) {
                array[i] = oldArray[i];
            }
            deallocator(oldArray);
        }

        for (int i = (int)theSize++; i > pos; --i) {
            array[i] = array[i - 1];
        }
        array[pos] = t;
    }


    void erase(unsigned int pos) {
        if (pos < theSize) {
            --theSize;
            for (unsigned int i = pos; i < theSize; ++i) {
                array[i] = array[i + 1];
            }
        }
    }

private:
    T* allocator(unsigned int size) {
        return new T[size];
    }

    void deallocator(T* arr) {
        if (arr)
            delete[] arr;
    }
private:
    T* array;
    unsigned int    theSize;
    unsigned int    theCapacity;
};

void printfVector(Varray<int>& vector1) {
    for (unsigned int i = 0; i < vector1.size(); ++i) {
        cout << vector1[i] << ",";
    }
    cout << "alloc size = " << vector1.capacity() << ",size = " << vector1.size() << endl;
}

int main() {
    Varray<int> Varray1;
    Varray<int> Varray2(0, 10);
    Varray2.push_front(1);
    Varray2.erase(11);
    printfVector(Varray2);
    Varray1.push_back(2);
    Varray1.push_front(1);
    printfVector(Varray1);
    Varray1.insert_after(1, 3);
    printfVector(Varray1);

    Varray2 = Varray1;
    Varray2.insert_before(0, 0);
    Varray2.insert_before(1, -1);
    printfVector(Varray2);
    return 0;
}
